home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / prolog / sbprolog / sbp.zoo / sbp_v3.1 / auxil / oozext.c < prev    next >
C/C++ Source or Header  |  1992-02-16  |  11KB  |  360 lines

  1. /* oozext.c -- extracts files from archive */
  2.  
  3. /* Main extraction module.  This file is public domain.
  4.  
  5.                                    -- Rahul Dhesi 1991/07/07
  6.  
  7. The function fixfname() is currently defined to be empty but may be
  8. activated if needed to fix filename syntax to be legal for your
  9. computer system.  Look near the end of this file for instructions and
  10. a sample implementation of fixfname().  Currently, fixfname() is used
  11. only if the symbol FIXFNAME is defined.
  12. */
  13.  
  14. #include "booz.h"
  15. #include "zoo.h"
  16. #include <stdio.h>
  17.  
  18. extern unsigned int crccode;
  19.  
  20. int needed ();
  21. extern char long_name[];
  22.  
  23. int oozext (char *zoo_path, char *option, int argc, char *argv[])
  24.  
  25. {
  26. FILE *zoofile;                            /* open archive */
  27. FILE *this_file;                          /* file to extract */
  28. long next_ptr;                            /* pointer to within archive */
  29. struct zoo_header zoo_header;             /* header for archive */
  30. int status;                               /* error status */
  31. struct direntry direntry;                 /* directory entry */
  32. int all = 0;                              /* overwrite all? */
  33. static char vermsg[] = "A higher version of Ooz is needed to extract ";
  34. int exitstat = 0;                         /* return code */
  35. int first_time = 1;
  36. static char *month_list="000JanFebMarAprMayJunJulAugSepOctNovDec";
  37.  
  38. {
  39.  
  40. #ifndef ARM
  41.    /* If no dot in name, add ".zoo" extension */
  42.    char *p;
  43.    p = zoo_path;
  44.    while (*p != '\0' && *p != '.')
  45.       p++;
  46.    if (*p != '.') {  /* no dot found */
  47.       p = malloc (strlen (zoo_path) + 5);
  48.       if (p == (char *) 0)
  49.          memerr();
  50.       strcpy (p, zoo_path);
  51.       strcat (p, ".zoo");
  52.       zoo_path = p;
  53.    }
  54. #endif
  55. }
  56.  
  57. zoofile = OPEN(zoo_path);
  58.  
  59. if (zoofile == NULL)
  60.    prterror ('f', "Could not open ", zoo_path, "\n");
  61.  
  62. /* read header */
  63. rd_zooh (&zoo_header, zoofile);
  64. fseek(zoofile, zoo_header.zoo_start, 0); /* seek to where data begins */
  65.  
  66. while (1) {
  67.    rd_dir (&direntry, zoofile);
  68.  
  69.          if (direntry.zoo_tag != ZOO_TAG)
  70.          prterror ('f', "Bad entry in archive\n", 
  71.             ((char *) 0), ((char *) 0));
  72.    if (direntry.next == 0L) {                /* END OF CHAIN */
  73.       break;                                 /* EXIT on end of chain */
  74.    }
  75.    next_ptr = direntry.next;                 /* ptr to next dir entry */
  76.  
  77.       /* See if this file is wanted */
  78.       if (!needed (long_name, argc, argv)) {
  79.          goto loop_again;
  80.       }
  81.  
  82.   /* If list needed, give information and loop again */
  83.    if (*option == 'l') {
  84.       char outstr[80];
  85.       char buf[20];
  86.       int year, month, day, hours, min, sec;
  87.       int size_factor;
  88.       size_factor = cfactor (direntry.org_size, direntry.size_now);
  89.    
  90.       year  =  ((unsigned int) direntry.date >> 9) & 0x7f;
  91.       month =  ((unsigned int) direntry.date >> 5) & 0x0f;
  92.       day   =  direntry.date        & 0x1f;
  93.       
  94.       hours =  ((unsigned int) direntry.time >> 11)& 0x1f;
  95.       min   =  ((unsigned int) direntry.time >> 5) & 0x3f;
  96.       sec   =  ((unsigned int) direntry.time & 0x1f) * 2;
  97.  
  98.       if (first_time) {
  99.          putstr ("Length    CF  Size Now  Date      Time\n");
  100.          putstr ("--------  --- --------  --------- --------\n");
  101.          first_time = 0;
  102.       }
  103.       strcpy (outstr, itoa(' ', direntry.org_size, buf, 9));
  104.       strcat (outstr, itoa(' ',(long) size_factor, buf, 5));
  105.       strcat (outstr, "% ");
  106.       strcat (outstr, itoa(' ',direntry.size_now, buf, 9));
  107.       strcat (outstr, "  ");
  108.       strcat (outstr, itoa(' ',(long) day, buf, 3));
  109.       strcat (outstr, " ");
  110.       strncat (outstr, &month_list[month*3], 3);
  111.       strcat (outstr, " ");
  112.       if (day && month)
  113.          strcat (outstr, itoa(' ',(long) (year+80) % 100, buf, 3));
  114.       else
  115.          strcat (outstr, itoa(' ',0L, buf, 3));
  116.       strcat (outstr, " ");
  117.       strcat (outstr, itoa('0',(long) hours, buf, 3));
  118.       strcat (outstr, ":");
  119.       strcat (outstr, itoa('0',(long) min, buf, 3));
  120.       strcat (outstr, ":");
  121.       strcat (outstr, itoa('0',(long) sec, buf, 3));
  122.       strcat (outstr, "  ");
  123.       strcat (outstr, long_name);
  124.       strcat (outstr, "\n");
  125.       putstr (outstr);
  126.  
  127. #ifdef COMMENT
  128.       printf ("%8lu %3u%% %8lu  %2d %-.3s %02d %02d:%02d:%02d  ",  
  129.                direntry.org_size, 
  130.                size_factor, direntry.size_now, 
  131.                day, &month_list[month*3], 
  132.                (day && month) ?  (year+80) % 100 : 0,
  133.                hours, min, sec);
  134.       printf ("%s\n", long_name);
  135. #endif
  136.  
  137.      goto loop_again;
  138.    }
  139.  
  140.  
  141.    if (direntry.major_ver > 2 ||
  142.          (direntry.major_ver == 2 && direntry.minor_ver > 1)) {
  143.       prterror ('e', vermsg, long_name, "\n");
  144.       goto loop_again;
  145.    }
  146.  
  147. #ifdef FIXFNAME
  148.    /* Make the filename syntax acceptable to the host system */
  149.          fixfname (long_name);
  150. #endif
  151.  
  152.  
  153.    /* See if this file already exists */
  154.  
  155.    if (*option != 't' && !all) {
  156.       this_file = OPEN(long_name);
  157.       if (this_file != NULL) {
  158.          char ans[2];
  159.          char ans2[2];
  160.          fclose(this_file);
  161.    
  162.          do {
  163.             prterror ('m', "Overwrite ", long_name, " (Yes/No/All)? ");
  164.             fread(ans, 1, 1, stdin);
  165.             do {
  166.                fread(ans2, 1, 1, stdin);
  167.             } while (*ans2 != '\n');
  168.          }  while (*ans != 'y' && *ans != 'Y' && 
  169.                    *ans != 'n' && *ans != 'N' &&
  170.                    *ans != 'a' && *ans != 'A');    
  171.    
  172.          if (*ans == 'a' || *ans == 'A')
  173.             all++;
  174.          if (*ans == 'n' || *ans == 'N') {
  175.             prterror ('m', "Skipping ", long_name, "\n");
  176.             goto loop_again;
  177.          }
  178.       }
  179.    }
  180.  
  181.    if (*option == 't')
  182.       this_file = NULL;
  183.          else {
  184.                         int retry=2;
  185.                         do {
  186.                                 retry--;
  187.                                 this_file = CREATE(long_name);
  188.                                 if( !this_file ) build_dirs( long_name );
  189.                         } while( !this_file && retry );
  190.          }
  191.  
  192.    if (*option != 't' && this_file == NULL) {
  193.       prterror ('e', "Could not open ", long_name, " for output.\n");
  194.    } else {
  195.       fseek(zoofile, direntry.offset, 0);
  196.       crccode = 0;      /* Initialize CRC before extraction */
  197.       putstr(long_name);
  198.       putstr(" ");
  199.  
  200.       if (direntry.packing_method == 0)
  201.                                  status = getfile(zoofile, this_file, direntry.size_now, long_name);
  202.                         else if (direntry.packing_method == 1)
  203.                                  status = lzd(zoofile, this_file, long_name); /* uncompress */
  204.                         else if (direntry.packing_method == 2)
  205.                                  status = lzh_decode(zoofile, this_file, long_name); /* uncompress */
  206.                         else
  207.                                  prterror ('e', vermsg, long_name, "\n");
  208.                         if (status != 0) {
  209. #ifdef ARM
  210.                                            remove(long_name);
  211. #else
  212.                                            unlink(long_name);
  213. #endif
  214.                                  if (status == 1) {
  215.                                                 memerr();
  216.                                  } else
  217.                                                 prterror ('e', "I/O error writing ", long_name, "\n");
  218.                         } else {
  219.          if (direntry.file_crc != crccode) {
  220.             putstr ("<--\007WARNING:  Bad CRC.\n");
  221.             exitstat = 1;
  222.          } else {
  223.             putstr ("\n");
  224.          }
  225.       } /* end if */
  226.    } /* end if */
  227.  
  228.    if (*option != 't' && this_file)
  229.       fclose(this_file);
  230.  
  231. loop_again:
  232.    fseek(zoofile, next_ptr, 0); /* ..seek to next dir entry */
  233. } /* end while */
  234. fclose(zoofile);
  235. exit (exitstat);
  236. } /* end oozext */
  237.  
  238. /*
  239. Function fixfname() fixes the syntax of the supplied filename so it is
  240. acceptable to the host system.  We call the standard string function 
  241. strchr(s, c) which searches a string s for a character c and returns
  242. a pointer to it or returns NULL if not found.  The scheme below
  243. strips the 8th bit and changes control characters to corresponding 
  244. printable characters (e.g.  ^A becomes A).
  245.  
  246. As supplied, fixfname() is activated only if the symbol FIXFNAME
  247. is defined.
  248. */
  249.  
  250. #ifdef ARM
  251. int fixfname( char *fname )
  252. {
  253.         char *p;
  254.         char *last_dot;
  255.         char tmp[100];
  256.  
  257.         while(p=strchr(fname,'$'))    *p='_';
  258.  
  259.         last_dot=strrchr(fname,'.');
  260.         if( last_dot ) {
  261.                         while( (p=strchr(fname,'.'))!=last_dot )  *p='_';
  262.                         if  ((p=strrchr (fname,'/')) && last_dot < p)
  263.                             *last_dot = '_';   /* for version number 3.1 */
  264.         }
  265.  
  266.  
  267.         if( strcmp( last_dot, ".c" )==0 || strcmp( last_dot, ".h" )==0 ) {
  268.                 p=strrchr( fname, '/' );
  269.                 if( !p ) {
  270.                         p=fname;
  271.                 } else {
  272.                         p++;
  273.                 }
  274.                 strcpy( tmp, p );
  275.                 *strchr( tmp, '.' )='\0';
  276.                 strcpy( p, last_dot+1 );
  277.                 strcat( p, "." );
  278.                 strcat( p, tmp );
  279.         } else {
  280.                 *last_dot='_';
  281.         }
  282.         while( p=strchr( fname, '/' ) ) *p='.';
  283.         strrchr(fname,'.')[10]='\0';
  284.  
  285. }
  286.  
  287. int build_dirs( char *name )
  288. {
  289.         char *p,*pe;
  290.         char cmd [256];
  291.  
  292.         for( p=name, pe=strchr(p,'.') ; pe ; p=pe+1, pe=strchr(p,'.') ) {
  293.                 *pe='\0';
  294.                 sprintf (cmd,"*cdir %s\n",name);
  295.                 system  (cmd);
  296.                 *pe='.';
  297.         }
  298. }
  299. #endif
  300.  
  301. #ifdef ATARI
  302. int fixfname( char *fname )
  303. {
  304.         char *p;
  305.         char *last_dot=NULL;
  306.  
  307.         for( p=fname ; *p ; p++ ) {
  308.                 if( *p=='/' ) {
  309.                         last_dot=NULL;
  310.                         *p='\\';
  311.                 }
  312.                 if( *p=='.' ) {
  313.                         if( last_dot ) *last_dot='_';
  314.                         last_dot=p;
  315.                 }
  316.         }
  317.         if( strcmp( fname+strlen(fname)-11, "$compile1.P" )==0 ) {
  318.                 strcpy( fname+strlen(fname)-11, "$compil1.P" );
  319.         }
  320.  
  321.         if( strcmp( fname+strlen(fname)-12, "$asmpass11.P")==0 ) {
  322.                 strcpy( fname+strlen(fname)-12, "$asmpas11.P" );
  323.   }
  324.  
  325.         if( strcmp( fname+strlen(fname)-12, "$asmpass21.P")==0 ) {
  326.                 strcpy( fname+strlen(fname)-12, "$asmpas21.P" );
  327.   }
  328. }
  329.  
  330. #ifdef __TURBOC__
  331. #include <tos.h>
  332. #else
  333. #include <osbind.h>
  334. #endif
  335.  
  336. int build_dirs( char *name )
  337. {
  338.         char *p,*pe;
  339.  
  340.         for( p=name, pe=strchr(p,'\\') ; pe ; p=pe+1, pe=strchr(p,'\\') ) {
  341.                 *pe='\0';
  342.                 Dcreate( name );
  343.                 *pe='\\';
  344.         }
  345. }
  346. #endif
  347.  
  348. #ifdef AMIGA
  349. int build_dirs( char *name )
  350. {
  351.         char *p,*pe;
  352.  
  353.         for( p=name, pe=strchr(p,'/') ; pe ; p=pe+1, pe=strchr(p,'/') ) {
  354.                 *pe='\0';
  355.                 mkdir( name );
  356.                 *pe='/';
  357.         }
  358. }
  359. #endif
  360.